using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace System.Collections.Generic {
    class Matrix<T> {
        private T[,] matrix;
        private int row_length;
        private int col_length;

        private Matrix() { }

        public Matrix(int rows, int cols) {
            if (rows < 0 || cols < 0) {
                throw new IndexOutOfRangeException("Matrix Initialization failed. Rows: " + rows + " Columns: " + cols);
            } else {
                this.matrix = new T[rows, cols];
                row_length = rows;
                col_length = cols;
            }
        }

        public T getFromCell(int row, int col) {
            if (!(row < 0 ||
                row >= row_length ||
                col < 0 ||
                col >= col_length)) {
                return this.matrix[row, col];
            } else {
                throw new IndexOutOfRangeException("Can not get element from row: " + row + " column: " + col );
            }
        }

        public T getFromCell(Point point) {
            int row = point.X;
            int col = point.Y;

            if (!(row < 0 ||
                row >= row_length ||
                col < 0 ||
                col >= col_length)) {
                return this.matrix[row, col];
            } else {
                throw new IndexOutOfRangeException("Can not get element from row: " + row + " column: " + col);
            }
        }

        public void setCellTo(int row, int col, T toSet) {
            if (!(row < 0 ||
                row >= row_length ||
                col < 0 ||
                col >= col_length)) {
                this.matrix[row, col] = toSet;
            } else {
                throw new IndexOutOfRangeException("Can not set element from row: " + row + " column: " + col);
            }
        }

        public void resetCell(int row, int col) {
            if (!(row < 0 ||
                row >= row_length ||
                col < 0 ||
                col >= col_length)) {
                this.matrix[row, col] = default(T);
            } else {
                throw new IndexOutOfRangeException("Can not clear element from row: " + row + " column: " + col);
            }
        }
    }
}
